Skip to content

Derive isRecording from coordinator state machine#1

Closed
Newarr wants to merge 3 commits intomainfrom
refactor/derive-isrecording-from-state
Closed

Derive isRecording from coordinator state machine#1
Newarr wants to merge 3 commits intomainfrom
refactor/derive-isrecording-from-state

Conversation

@Newarr
Copy link
Copy Markdown
Owner

@Newarr Newarr commented Mar 20, 2026

Problem

isRecording is a writable stored property on AppCoordinator, set by ContentView's 100ms polling loop via synchronizeDerivedState(). Any consumer reading this property outside that loop -- such as a menu bar controller or termination guard -- sees stale values when the main window is hidden.

This is a prerequisite for the menu bar background mode feature, where recording state must be accurate without any visible window.

Solution

Replace the writable _isRecording / getter / setter with a computed property that derives directly from the coordinator's authoritative MeetingState:

Before After
@ObservationIgnored nonisolated(unsafe) private var _isRecording = false var isRecording: Bool { if case .recording = state { return true }; return false }
Set by ContentView polling loop Derived from state machine
Stale when window hidden Always accurate

Changed files

File Change
AppCoordinator.swift Replace stored property with computed property
ContentView.swift Remove coordinator.isRecording = currentViewState.isRunning setter call

Test plan

  • Start recording, verify isRecording returns true
  • Stop recording, verify isRecording returns false
  • Close main window while recording, verify isRecording still reflects true state
  • Existing ui-smoke tests pass (no behavior change for consumers that only read the property)

PR 1 of 4 in the menu bar background mode series.
Next: #2 Extract service initialization for headless operation

@Newarr Newarr force-pushed the refactor/derive-isrecording-from-state branch from 08cabe2 to 705ff94 Compare March 20, 2026 18:48
isRecording was a writable stored property set by ContentView's 100ms
polling loop. Any consumer outside that loop saw stale values when
the main window was hidden. Replace with a computed property that
reads directly from the coordinator's authoritative MeetingState.

Also add MeetingMetadata.manual() factory to eliminate duplicate
inline construction of manual session metadata.
@Newarr Newarr force-pushed the refactor/derive-isrecording-from-state branch from 705ff94 to 27fd880 Compare March 20, 2026 19:01
Newarr pushed a commit that referenced this pull request Mar 21, 2026
Research-backed improvements to transcript refinement:

- Add temperature parameter to LLMCompleting protocol and OpenRouterClient.
  Refinement uses temperature=0 for deterministic output (OpenAI Cookbook
  recommendation for correction tasks).
- Implement detect-then-correct pattern: heuristic needsCleanup() check
  skips clean-looking text before hitting the LLM, reducing unnecessary
  API calls and avoiding over-correction (#1 problem per research).
- Add backchannel preservation rule: keep "uh-huh", "yeah", "mm-hmm"
  when used as direct responses (professional transcription standard).
- Consolidate 8 separate MainActor.run calls into single atomic read,
  preventing TOCTOU issues if settings change mid-read.
- Remove dead contextWindowSize constant.
- Add "Meeting Languages" label to settings for accessibility.
- Tests: add needsCleanup tests, temperature verification, clean-text
  skipping, question bypass of needsCleanup. All test utterances updated
  to contain disfluency markers so they pass the new gate.

https://claude.ai/code/session_01WgtdecTp9R6NYyLNv1uQSc
Newarr pushed a commit that referenced this pull request Mar 22, 2026


- Make cancel() async and await task completion to prevent data races (#1)
- Move session-switch guard before backfillRefinedText to prevent stale writes (#3)
- Cancel cleanup engine in teardownMeetingDetection (#4)
- Add .pre-llm.md backup before overwriting Markdown with LLM sections (yazinsai#10)
- Add safety documentation for nonisolated(unsafe) vars (#2)
- Add unit tests for chunkRecords and parseResponse (#5)

https://claude.ai/code/session_01QTKjQDQpoVqFrPJM8bp218
Newarr pushed a commit that referenced this pull request Mar 26, 2026
… refinement

Integrate Cohere Transcribe (2B-param Conformer ASR, #1 on Open ASR Leaderboard
at 5.42% WER) as a CoreML-based transcription backend for OpenOats. The model is
converted via coremltools with INT4 quantization (~1.1GB) targeting Neural Engine.

New files:
- Scripts/convert_cohere_transcribe.py: PyTorch → CoreML conversion pipeline
  splitting model into ConformerEncoder + TransformerDecoder .mlpackage files
  with EnumeratedShapes bucketing and INT4/INT8/palettization options
- CohereTranscribeBackend.swift: CoreML-based TranscriptionBackend with model
  download, mel spectrogram computation, and autoregressive decoding
- BatchTranscriptionEngine.swift: Post-meeting batch re-transcription actor
  that processes saved audio through Cohere Transcribe for higher accuracy

Modified files:
- AppSettings: .cohereTranscribe enum case, enableBatchRefinement setting
- AppCoordinator: Async batch re-transcription after session finalization
  with timestamp-based speaker label alignment
- AudioRecorder: Per-channel M4A export (mic/system) for speaker-aware batch
- SessionStore: backfillBatchRefinedText for index-based JSONL updates
- AppRuntime: Wire savePerChannelAudio from enableBatchRefinement setting

https://claude.ai/code/session_019DCqs5ak92DYNbHQA3rjvh
@Newarr Newarr closed this Mar 30, 2026
@Newarr Newarr deleted the refactor/derive-isrecording-from-state branch March 30, 2026 11:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants